﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZXing;
using ZXing.QrCode;
using ZXing.QrCode.Internal;

namespace QrTest
{
    static class Program
    {
        //static byte[][] ToIntMatrix(this ByteMatrix _mat)
        //{
        //    var mat = _mat.Array;
        //    int top = -1, left = -1;

        //    for (int i = 0; i < mat.Length; i++)
        //    {
        //        for (int j = 0; j < mat[0].Length; j++)
        //        {
        //            if (mat[i][j] == 0)
        //            {
        //                if (left < 0)
        //                    left = j;
        //                if (top < 0)
        //                    top = i;
        //                if (top >= 0 && left >= 0)
        //                    break;
        //            }

        //        }
        //        if (top >= 0 && left >= 0)
        //            break;
        //    }

        //    var width = 21;
        //    var height = 21;
        //    var res = new int[height][];
        //    for (int i = 0; i < height; i++)
        //    {
        //        res[i] = new int[width];
        //        for (int j = 0; j < width; j++)
        //        {
        //            res[i][j] = mat[i * 3 + top][j * 3 + left];
        //        }
        //    }
        //    return res;
        //}

        static void Print(byte[][] mat)
        {
            for (int i = 0; i < mat.Length; i++)
            {
                for (int j = 0; j < mat[i].Length; j++)
                {
                    Console.Write(mat[i][j] == 0 ? " " : "#");
                }
                Console.WriteLine();
            }
        }

        static void GenerateAndDraw(string text)
        {
            QRCode q = GetQrCode(text);


            //var qr = writer.Encode(text);//writer.encode(text, BarcodeFormat.QR_CODE, 10, 10);
            Console.WriteLine("found " + q.Version.DimensionForVersion);
            
            Print(q.Matrix.Array);


        }

        private static QRCode GetQrCode(string text)
        {
            QRCode q = ZXing.QrCode.Internal.Encoder.encode(text, ErrorCorrectionLevel.H);

            if (q.Version != ZXing.QrCode.Internal.Version.getVersionForNumber(1) || q.Mode != Mode.NUMERIC)
            {
                Console.WriteLine("greater version or non numeric");
                throw new Exception("greater version or non numeric");

            }
            return q;
        }

        public static byte[] ToArray(this byte[][] mat)
        {
            int c = 0;
            var res = new byte[mat.Length * mat.Length];
            for (int i = 0; i < mat.Length; i++)
            {
                for (int j = 0; j < mat.Length; j++)
                {
                    res[c++] = mat[i][j];
                }
            }
            return res;
        }

        public static Tuple<long, byte[]>[] CreateDataSet(int count, int seed = -1)
        {
            var rand = seed == -1 ? new Random() : new Random(seed);
            var res = new Tuple<long, byte[]>[count];

            for (int i = 0; i < count; i++)
            {
                //var num = (long)(((double)rand.Next() / (double)int.MaxValue) * 100000000000000000.0);
                var num = (long)(rand.NextDouble() * 100000000000000000.0);
                var qr = GetQrCode(num.ToString());
                res[i] = new Tuple<long, byte[]>(num, qr.Matrix.Array.ToArray());
            }

            return res;
        }

        // versione 1 con error recover al max e' 10 caratteri a disegno
        static void Main(string[] args)
        {
            bool looping = true;

            Console.ForegroundColor = ConsoleColor.Black;
            Console.BackgroundColor = ConsoleColor.White;

            var dataset = CreateDataSet(1000, 0);

            while (looping)
            {
                var text = Console.ReadLine();
                looping = text != "exit";
                GenerateAndDraw(text);
            }

            //for (int i = 0; i < 256; i++)
            //{
            //    Console.WriteLine(i + " -> " + (char) i);
            //}


            //Console.ReadKey();
        }
    }
}
